package cc.fozone.note.view;

import javafx.beans.value.ChangeListener;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.EventHandler;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import netscape.javascript.JSException;
import cc.fozone.note.configuration.IConfiguration;

public class OutputView extends BorderPane implements IView {
	private IConfiguration<String, String> configuration;
	private WebView web;
	private WebEngine engine;
	private Worker<Void> worker;
	private ScrollBar yScrollBar, xScrollBar;

	private double scrollHeight = 0;

	private String styleClass = "content-output";

	public OutputView(IConfiguration<String, String> configuration) {
		// TODO Auto-generated constructor stub
		this.configuration = configuration;
		this.init();
	}

	@Override
	public void init() {
		// TODO Auto-generated method stub
		this.buildConfiguration();
		this.buildView();
	}

	@Override
	public void handle() {
		// TODO Auto-generated method stub
		engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {

			@Override
			public void handle(WebEvent<String> event) {
				// TODO Auto-generated method stub
				System.out.println(event.getData());
			}

		});

	}

	private void buildConfiguration() {
		// TODO Auto-generated method stub
		styleClass = configuration.get("app.content.outputStyleClass",
				styleClass);
	}

	private void buildView() {
		// TODO Auto-generated method stub
		web = new WebView();
		web.getStyleClass().addAll(styleClass);

		engine = web.getEngine();
		worker = engine.getLoadWorker();
		this.setCenter(web);
	}

	public void loadContent(String html) {
		this.engine.loadContent(html);
	}

	public void setScrollTop(double value) {
		try{
			engine.executeScript("document.body.scrollTop=" + value + ";");
		}catch(JSException e) {
			
		}
	}

	public void setScrollLeft(double value) {
		try {
			engine.executeScript("document.body.scrollLeft=" + value + ";");
		} catch(JSException e) {
			
		}
	}

	public double getScrollTop() {
		if (yScrollBar != null) {
			return yScrollBar.getValue();
		}
		return -1;
	}

	public double getScrollLeft() {
		return xScrollBar != null ? xScrollBar.getValue() : -1;
	}

	/**
	 * 对于Web类型的高度而言，主要考虑加载成功时的计算
	 */
	public void updateScrollHeight() {
		Object result = null;
		try {
			result = engine.executeScript("(function(){return document.documentElement.scrollHeight;})();");
		}catch(JSException e){
		}
		
		/*
		double height = -1;
		this.setScrollTop(100);
		ObservableList<Node> list = web.getChildrenUnmodifiable();
		for(Node node : list){
			if(node instanceof ScrollBar){
				ScrollBar bar = (ScrollBar) node;
				if(bar.getOrientation() == Orientation.VERTICAL) {
					height = ScrollPaneHelper.getBlankValue(bar);
					//System.out.println(bar.getUnitIncrement());
					//height = bar.getVisibleAmount();
					break;
				}
			}
		}
		this.scrollHeight = height;
		*/
		
		this.scrollHeight = Double.valueOf(result.toString());
	}

	public double getScrollHeight() {
		return scrollHeight;
	}

	public double getScrollWidth() {
		return 0;
	}

	public Worker<Void> getWorker() {
		return engine.getLoadWorker();
	}

	public boolean isLoaded() {
		return this.worker.getProgress() >= 1;
	}

	public void setOnStateChange(ChangeListener<State> listener) {
		this.worker.stateProperty().addListener(listener);
	}

	public void setOnWordDone(ChangeListener<Number> listener) {
		this.worker.workDoneProperty().addListener(listener);
	}
}